// 图表数据转换工具

/**
 * 将时间序列数据转换为折线图需要的格式
 * @param {Array} timeSeriesData 时间序列数据
 * @param {string} labelKey 标签字段名
 * @param {Array<{key: string, label: string, color: string}>} datasets 数据集配置
 * @returns {Object} 折线图数据对象
 */
export function transformTimeSeriesData(timeSeriesData, labelKey, datasets) {
  if (!timeSeriesData || !timeSeriesData.length) {
    return { labels: [], datasets: [] }
  }

  // 提取标签
  const labels = timeSeriesData.map((item) => item[labelKey])

  // 处理数据集
  const chartDatasets = datasets.map((dataset) => {
    return {
      label: dataset.label,
      data: timeSeriesData.map((item) => item[dataset.key]),
      borderColor: dataset.color,
      backgroundColor: addAlpha(dataset.color, 0.2),
      tension: 0.4,
    }
  })

  return { labels, datasets: chartDatasets }
}

/**
 * 将饼图数据转换为Chart.js需要的格式
 * @param {Array} pieData 饼图数据
 * @param {string} labelKey 标签字段名
 * @param {string} valueKey 值字段名
 * @param {Array<string>} [customColors] 自定义颜色列表
 * @returns {Object} 饼图数据对象
 */
export function transformPieChartData(pieData, labelKey, valueKey, customColors) {
  if (!pieData || !pieData.length) {
    return { labels: [], datasets: [] }
  }

  // 默认颜色
  const defaultColors = [
    '#36A2EB',
    '#FF6384',
    '#FFCE56',
    '#4BC0C0',
    '#9966FF',
    '#FF9F40',
    '#C9CBCF',
    '#7AC142',
    '#F05A28',
    '#5D9CEC',
  ]

  // 使用提供的颜色或默认颜色
  const colors = customColors || defaultColors

  // 提取标签和数据
  const labels = pieData.map((item) => item[labelKey])
  const data = pieData.map((item) => item[valueKey])

  // 为每个切片分配颜色
  const backgroundColor = pieData.map((_, index) => {
    return colors[index % colors.length]
  })

  return {
    labels,
    datasets: [
      {
        data,
        backgroundColor,
        hoverOffset: 4,
      },
    ],
  }
}

/**
 * 将柱状图数据转换为Chart.js需要的格式
 * @param {Array} barData 柱状图数据
 * @param {string} labelKey 标签字段名
 * @param {Array<{key: string, label: string, color: string}>} datasets 数据集配置
 * @returns {Object} 柱状图数据对象
 */
export function transformBarChartData(barData, labelKey, datasets) {
  if (!barData || !barData.length) {
    return { labels: [], datasets: [] }
  }

  // 提取标签
  const labels = barData.map((item) => item[labelKey])

  // 处理数据集
  const chartDatasets = datasets.map((dataset) => {
    return {
      label: dataset.label,
      data: barData.map((item) => item[dataset.key]),
      backgroundColor: dataset.color,
      borderColor: darkenColor(dataset.color, 20),
      borderWidth: 1,
    }
  })

  return { labels, datasets: chartDatasets }
}

/**
 * 将关键词数据转换为词云需要的格式
 * @param {Array} keywords 关键词数据
 * @param {string} textKey 文本字段名
 * @param {string} weightKey 权重字段名
 * @returns {Array} 词云数据数组
 */
export function transformWordCloudData(keywords, textKey = 'text', weightKey = 'weight') {
  if (!keywords || !keywords.length) {
    return []
  }

  return keywords.map((item) => {
    return {
      text: item[textKey],
      value: item[weightKey],
    }
  })
}

/**
 * 工具函数：为颜色添加透明度
 * @param {string} color 颜色值（十六进制或RGB）
 * @param {number} alpha 透明度（0-1）
 * @returns {string} 带透明度的颜色值
 */
function addAlpha(color, alpha) {
  // 如果已经是rgba格式，直接替换透明度
  if (color.startsWith('rgba')) {
    return color.replace(/rgba\((.+?),\s*[\d\.]+\)/, `rgba($1, ${alpha})`)
  }

  // 如果是rgb格式，转换为rgba
  if (color.startsWith('rgb')) {
    return color.replace(/rgb\((.+?)\)/, `rgba($1, ${alpha})`)
  }

  // 如果是十六进制格式
  let r = 0,
    g = 0,
    b = 0

  // 3位十六进制
  if (color.length === 4) {
    r = parseInt(color[1] + color[1], 16)
    g = parseInt(color[2] + color[2], 16)
    b = parseInt(color[3] + color[3], 16)
  }
  // 6位十六进制
  else if (color.length === 7) {
    r = parseInt(color.substring(1, 3), 16)
    g = parseInt(color.substring(3, 5), 16)
    b = parseInt(color.substring(5, 7), 16)
  }

  return `rgba(${r}, ${g}, ${b}, ${alpha})`
}

/**
 * 工具函数：加深颜色
 * @param {string} color 颜色值（十六进制）
 * @param {number} amount 加深程度（0-255）
 * @returns {string} 加深后的颜色
 */
function darkenColor(color, amount) {
  // 去除#前缀
  let hex = color.replace('#', '')

  // 将3位十六进制扩展为6位
  if (hex.length === 3) {
    hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]
  }

  // 获取RGB值
  let r = parseInt(hex.substring(0, 2), 16)
  let g = parseInt(hex.substring(2, 4), 16)
  let b = parseInt(hex.substring(4, 6), 16)

  // 减少RGB值
  r = Math.max(0, r - amount)
  g = Math.max(0, g - amount)
  b = Math.max(0, b - amount)

  // 转回十六进制
  return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`
}

/**
 * 将数据转换为环形图格式
 * @param {Array<Object>} data 原始数据数组
 * @param {string} labelKey 标签字段键名
 * @param {string} valueKey 值字段键名
 * @param {Array<string>} [colors] 可选的颜色数组
 * @returns {Object} 环形图数据
 */
export function transformDoughnutChartData(data, labelKey, valueKey, colors) {
  if (!data || !data.length) return { labels: [], datasets: [{ data: [] }] }

  // 默认颜色数组
  const defaultColors = [
    '#409EFF',
    '#67C23A',
    '#E6A23C',
    '#F56C6C',
    '#909399',
    '#6b778c',
    '#b643cd',
    '#42CCA9',
    '#3963BC',
    '#9A69EC',
  ]

  // 提取标签
  const labels = data.map((item) => item[labelKey])

  // 提取数据
  const values = data.map((item) => item[valueKey] || 0)

  // 确定使用的颜色数组
  const usedColors = colors || defaultColors

  // 如果数据点数量超过颜色数组长度，循环使用颜色
  const backgroundColors = labels.map((_, index) => usedColors[index % usedColors.length])

  return {
    labels,
    datasets: [
      {
        data: values,
        backgroundColor: backgroundColors,
      },
    ],
  }
}

/**
 * 将数据转换为热力图格式
 * @param {Array<Object>} data 原始数据数组，每项包含x, y, value字段
 * @param {Array<string>} xLabels X轴标签
 * @param {Array<string>} yLabels Y轴标签
 * @returns {Object} 热力图数据
 */
export function transformHeatmapData(data, xLabels, yLabels) {
  if (!data || !data.length) return { data: [] }

  // 转换数据格式为[x, y, value]数组
  const heatmapData = data
    .map((item) => {
      const xIndex = xLabels.indexOf(item.x)
      const yIndex = yLabels.indexOf(item.y)

      if (xIndex === -1 || yIndex === -1) {
        console.warn('热力图数据点坐标超出范围', item)
        return null
      }

      return [xIndex, yIndex, item.value || 0]
    })
    .filter(Boolean)

  return {
    xLabels,
    yLabels,
    data: heatmapData,
  }
}

/**
 * 将数据转换为散点图格式
 * @param {Array<Object>} data 原始数据数组
 * @param {string} xKey X轴字段键名
 * @param {string} yKey Y轴字段键名
 * @param {string} [sizeKey] 可选的点大小字段键名
 * @param {string} [colorKey] 可选的点颜色字段键名
 * @param {Function} [colorMapper] 颜色映射函数，接收colorKey对应的值，返回颜色
 * @returns {Object} 散点图数据
 */
export function transformScatterData(data, xKey, yKey, sizeKey, colorKey, colorMapper) {
  if (!data || !data.length) return { datasets: [] }

  // 如果没有提供颜色映射函数，使用默认映射
  const defaultColorMapper = () => '#409EFF'
  const getColor = colorMapper || defaultColorMapper

  // 如果有colorKey，按colorKey分组数据
  if (colorKey) {
    // 提取所有唯一的颜色值
    const colorValues = [...new Set(data.map((item) => item[colorKey]))]

    // 为每个颜色值创建一个数据集
    const datasets = colorValues.map((colorValue) => {
      // 过滤出当前颜色值的数据点
      const points = data
        .filter((item) => item[colorKey] === colorValue)
        .map((item) => ({
          x: item[xKey] || 0,
          y: item[yKey] || 0,
          r: sizeKey ? Math.max(3, item[sizeKey] || 5) : 5,
        }))

      return {
        label: colorValue.toString(),
        data: points,
        backgroundColor: getColor(colorValue),
      }
    })

    return { datasets }
  }

  // 无需按颜色分组，创建单个数据集
  const points = data.map((item) => ({
    x: item[xKey] || 0,
    y: item[yKey] || 0,
    r: sizeKey ? Math.max(3, item[sizeKey] || 5) : 5,
  }))

  return {
    datasets: [
      {
        data: points,
        backgroundColor: '#409EFF',
      },
    ],
  }
}

/**
 * 将数据转换为雷达图格式
 * @param {Array<Object>} data 原始数据数组，每个对象代表一个样本
 * @param {string} labelKey 标签字段键名
 * @param {Array<{key: string, label: string}>} attributeKeys 属性字段配置
 * @param {Array<string>} [colors] 可选的颜色数组
 * @returns {Object} 雷达图数据
 */
export function transformRadarChartData(data, labelKey, attributeKeys, colors) {
  if (!data || !data.length) return { labels: [], datasets: [] }

  // 默认颜色数组
  const defaultColors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399']

  // 提取属性标签
  const labels = attributeKeys.map((attr) => attr.label || attr.key)

  // 确定使用的颜色数组
  const usedColors = colors || defaultColors

  // 构建数据集
  const datasets = data.map((item, index) => {
    const color = usedColors[index % usedColors.length]

    return {
      label: item[labelKey],
      data: attributeKeys.map((attr) => item[attr.key] || 0),
      borderColor: color,
      backgroundColor: color.replace('rgb', 'rgba').replace(')', ', 0.2)'),
    }
  })

  return { labels, datasets }
}

/**
 * 计算数据的基本统计信息
 * @param {Array<number>} values 数值数组
 * @returns {Object} 统计信息对象
 */
export function calculateStatistics(values) {
  if (!values || !values.length) {
    return {
      count: 0,
      sum: 0,
      mean: 0,
      median: 0,
      min: 0,
      max: 0,
      variance: 0,
      stdDev: 0,
    }
  }

  // 过滤有效数值
  const validValues = values.filter((v) => typeof v === 'number' && !isNaN(v))
  const count = validValues.length

  if (count === 0) {
    return {
      count: 0,
      sum: 0,
      mean: 0,
      median: 0,
      min: 0,
      max: 0,
      variance: 0,
      stdDev: 0,
    }
  }

  // 计算基本统计量
  const sum = validValues.reduce((acc, val) => acc + val, 0)
  const mean = sum / count

  // 排序后计算中位数
  const sorted = [...validValues].sort((a, b) => a - b)
  const median =
    count % 2 === 0
      ? (sorted[count / 2 - 1] + sorted[count / 2]) / 2
      : sorted[Math.floor(count / 2)]

  // 最小值和最大值
  const min = sorted[0]
  const max = sorted[count - 1]

  // 计算方差和标准差
  const variance = validValues.reduce((acc, val) => acc + Math.pow(val - mean, 2), 0) / count
  const stdDev = Math.sqrt(variance)

  return {
    count,
    sum,
    mean,
    median,
    min,
    max,
    variance,
    stdDev,
  }
}

/**
 * 将数据转换为CSV格式
 * @param {Array<Object>} data 原始数据数组
 * @param {Array<{key: string, label: string}>} columns 列配置
 * @returns {string} CSV格式字符串
 */
export function transformToCSV(data, columns) {
  if (!data || !data.length || !columns || !columns.length) {
    return ''
  }

  // 添加BOM以正确显示中文
  let csvContent = '\ufeff'

  // 添加表头
  csvContent +=
    columns
      .map((col) => {
        // 处理包含逗号的内容，用双引号包裹
        const label = col.label || col.key
        return label.includes(',') ? `"${label}"` : label
      })
      .join(',') + '\n'

  // 添加数据行
  data.forEach((row) => {
    const rowContent = columns
      .map((col) => {
        let cellValue = row[col.key]

        // 处理特殊类型
        if (cellValue === null || cellValue === undefined) {
          cellValue = ''
        } else if (typeof cellValue === 'object') {
          cellValue = JSON.stringify(cellValue)
        } else {
          cellValue = String(cellValue)
        }

        // 处理包含逗号、换行符或双引号的内容
        if (cellValue.includes(',') || cellValue.includes('\n') || cellValue.includes('"')) {
          // 将双引号替换为两个双引号
          cellValue = cellValue.replace(/"/g, '""')
          // 用双引号包裹
          cellValue = `"${cellValue}"`
        }

        return cellValue
      })
      .join(',')

    csvContent += rowContent + '\n'
  })

  return csvContent
}
